import random
from haystack.views import SearchView
from django.contrib.auth import authenticate, login, logout

from celery_tasks.qiniuyun.qiniu_storage import storage
from celery_tasks.sms.tasks import ccp_send_sms_code
from django.shortcuts import render
import json
import re
from django.http import JsonResponse, HttpResponse
from django.views import View
from django_redis import get_redis_connection
import logging

from ihome.libs.captcha.captcha import captcha
from ihome.libs.yuntongxun.ccp_sms import CCP
from ihome.settings.settings import URL
from ihome.utils.views import LoginRequiredMixin
from mod.models import House, Order, Area, User
from ywy.utils import pag

logger = logging.getLogger('django')



'''图片验证码'''
# cur： 验证码编号 pre： 上一次验证码编号
class ImageCodeView(View):

    def get(self, request):
        cur = request.GET.get('cur')
        pre = request.GET.get('pre')
        # cur: 浏览器端当前生成的唯一id
        # 用captcha 工具 生成图形验证码和对应文本
        text, image = captcha.generate_captcha()
        # 创建连接对象
        redis_conn = get_redis_connection('verify')
        #  对象.setex 　保存数据到redis库并设置有效期

        redis_conn.setex('image_%s' % cur, 300, text)
        print('image_%s' % cur)
        print(text)

        return HttpResponse(image,
                            content_type='image/jpg')


class SMSCodeView(View):

    def post(self, request):

        # 接收参数
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')

        # 创建链接到redis的对象
        redis_conn = get_redis_connection('verify')

        # 查看flag数据是否存在,存在,说明两次验证码间隔没过60s,返回
        # send_flag = redis_conn.get('send_flag_%s' % mobile)
        # if send_flag:
        #     return JsonResponse({'errno': 400, 'errmsg': '发送短信过于频繁'})

        id = json_dict.get('id')
        image_client = json_dict.get('text')

        #　校验参数
        if not all([mobile, id, image_client]):
            return JsonResponse({'errno': 400, 'errmsg': '缺少必传参数'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'errno': 400, 'errmsg': 'mobile格式有误'})

        print('image_%s' % id)
        # 提取图形验证码
        image_server = redis_conn.get('image_%s' % id)

        if image_server is None:
            return JsonResponse({'errno': 400, 'errmsg': '图形验证码失效'})

        # 删除图形验证码，避免恶意测试
        try:
            redis_conn.delete('image_%s' % id)
        except Exception as e:
            logger.error(e)

        # 比对图形验证码
        if image_client.lower() != image_server.decode().lower():
            return JsonResponse({'errno': 400, 'errmsg': '图形验证码错误'})

        # 生成６位数字短信验证码
        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # 创建管道对象:
        pl = redis_conn.pipeline()

        # 保存短信验证码
        redis_conn.setex('sms_%s' % mobile, 300, sms_code)

        # 往 redis 中写入一个有效期为60s的flag数据
        # redis_conn.setex('send_flag_%s' % mobile, 60, 1)
        print(sms_code)
        # 执行管道:
        pl.execute()

        # CCP().send_template_sms(mobile,[sms_code, 5], 1)
        ccp_send_sms_code.delay(mobile, sms_code)

        return JsonResponse({"errno": "0", "errmsg": "发送成功"})


class SessionView(View):
    def post(self,request):

        json_dict  = json.loads(request.body.decode())
        mobile = json_dict['mobile']
        password = json_dict['password']

        if not all([mobile,password]):
            return JsonResponse({
                 "errno": "0",
                 "errmsg": "登录成功"
            })
        #　账号认证
        user = authenticate(username=mobile,
                            password=password)
        if user is None:
            return JsonResponse({
                "errno": "4104",
                "errmsg": "用户不存在或未激活"
            })
        login(request,user)

        response = JsonResponse({
                 "errno": "0",
                 "errmsg": "登录成功"
            })
        #用户登录和注册的时候, 都需要把用户的信息写入到cookie.
        response.set_cookie('mobile',mobile,3600*24*14)

        return response

    def get(self, request):
        print(request.user)
        if request.user.is_authenticated:
            print(request.user.username, type(request.user.username))
            return JsonResponse({
                        "errno": "0",
                        "errmsg": "已登录",
                        "data": {
                            'user_id': request.user.id,
                            "name": request.user.username
                        }
                    })
        else:
            return JsonResponse({
                        "errno": "4101",
                        "errmsg": "未登录"
                    })

    def delete(self, request):
        """实现退出登录逻辑"""

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = JsonResponse({'errno':0,
                                 'errmsg':'ok'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('mobile')

        # 返回响应
        return response


class CertificationView(View):
    def post(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        real_name = json_dict.get('real_name')
        id_card = json_dict.get('id_card')

        # 校验参数
        if not all([real_name, id_card]):
            return JsonResponse({"errno": "0", "errmsg": "缺少必传参数"})

        if not re.match(r'^[\u4E00-\u9FA5]{2,7}$', real_name):
            return JsonResponse({"errno": "0", "errmsg": "请输入真实姓名！"})

        # if not re.match(r'( ^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)', id_card):
        #     return JsonResponse({"errno": "0", "errmsg": "请输入真实身份证号！"})

        try:
            request.user.real_name = real_name
            request.user.id_card = id_card
            request.user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400, 'errmsg': '保存邮箱地址失败'})

        return JsonResponse({"errno": "0", "errmsg": "认证信息保存成功"})

    def get(self, request):
        if request.user.real_name:
            return JsonResponse({"errno": "0",
                                 "errmsg": "认证信息保存成功",
                                 'data': {'real_name': request.user.real_name, 'id_card': request.user.id_card}
                                })
        else:
            return JsonResponse({"errno": "4104", "errmsg": "用户未认证"})




class ImageUpdateView(LoginRequiredMixin, View):
    def post(self, request):
        pass


class MySearchView(View):
    def get(self, request):
        i = 0
        count = 0
        dday = 0
        # 接收参数
        area_id = request.GET.get('aid')
        start_day = request.GET.get('sd')
        end_day = request.GET.get('ed')
        sort_key = request.GET.get('sk')
        page = request.GET.get('p')
        area = Area.objects.get(id = area_id)

        # 校验参数，分批过滤
        if area_id:
            houses = House.objects.filter(area_id=area_id)
        else:
            houses = House.objects.all()

        house_list = []
        if start_day and end_day:
            for house in houses:
                flag = 1
                orders = house.order_set.all()
                dict = Order.ORDER_STATUS
                for order in orders:
                    # 无效订单状态，跳出
                    if order.status in [dict["CANCELED"], dict["REJECTED"]]:
                        continue
                    # 如果
                    if not (start_day > order.end_date.strftime("%Y-%m-%d") or end_day < order.begin_date.strftime("%Y-%m-%d")):
                        flag = 0
                if flag == 1:
                    house_list.append(house)
                    count += 1
        elif (not start_day) and (not end_day):
            house_list = houses
            count = len(houses)
        else:
            if start_day and (not end_day):
                dday = start_day
            else:
                dday = end_day
            for house in houses:
                flag = 1
                orders = house.order_set.all()
                dict = Order.ORDER_STATUS
                for order in orders:
                    # 无效订单状态，跳出
                    if order.status in [dict["CANCELED"], dict["REJECTED"]]:
                        continue
                    # 如果
                    if not (dday > order.end_date.strftime("%Y-%m-%d") or dday < order.begin_date.strftime("%Y-%m-%d")):
                        flag = 0
                if flag == 1:
                    house_list.append(house)
                    count += 1
        l = len(house_list)
        # 检查页数是否溢出
        print("hello")
        p = (count + 1)//2
        a = (int(page) * 2 - 1)
        if a > len(house_list):
            return JsonResponse({"errmsg": "最多只有%d页" % p, "errno": "4103"})
        # 调用utils返回对应page页列表
        house_list = pag(house_list, page, sort_key)

        result_list = []
        for house in house_list:
            result_list.append({
                "house_id": house.id,
                "img_url": house.index_image_url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": str(house.user.avatar)
            })

        return JsonResponse({
                                "data": {
                                    "houses": result_list,
                                    "total_page": p
                                },
                                "errmsg": "请求成功",
                                "errno": "0"
                            })

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        title = json_dict['title']
        area_id = json_dict['area_id']
        address = json_dict['address']
        room_count = json_dict['room_count']
        acreage = json_dict['acreage']
        unit = json_dict['unit']
        capacity = json_dict['capacity']
        beds = json_dict['beds']
        deposit = json_dict['deposit']
        min_days = json_dict['min_days']
        max_days = json_dict['max_days']
        facility = json_dict['facility']
        try:
            house = House.objects.create(
                user_id=request.user.id,
                title=title,
                area_id=area_id,
                # facility = None,
                address=address
                # room_count= room_count,
                # acreage = acreage,
                # unit = unit,
                # capacity = capacity,
                # beds = beds,
                # deposit = int(deposit),
                # min_days = min_days,
                # max_days= max_days,

            )
        except Exception as e:
            return JsonResponse({
                "errmsg": "获取数据失败",
                "errno": "4002"
            })
        return JsonResponse({
            "data": {'house_id': house.id},
            "errmsg": "发布成功",
            "errno": "0"
        })
# 下订单
class OrderView(View):
    def post(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        house_id = json_dict.get('house_id')
        start = json_dict.get('start_date')
        end = json_dict.get('end_date')
        house = House.objects.get(id=house_id)

        # 获取与该房屋相关的所有订单
        orders = house.order_set.all()
        dict = Order.ORDER_STATUS
        for order in orders:
            if order.status in [dict["CANCELED"], dict["REJECTED"]]:
                continue
            if not (start > order.end_date or end < order.begin_date):
                return JsonResponse({"errno": "4101", "errmsg": "该时间段已被预定"})

        order = Order.objects.create(
                        user=request.user,
                        house=house,
                        begin_date=start,
                        end_date=end,
                        days=end - start + 1,
                        house_price=house.price,
                        amount=(end - start + 1) * house.price,
                        status=dict['WAIT_ACCEPT'],
                        comment=None)

        return JsonResponse({
                    "data": {
                        "order_id": order.id
                    },
                    "errno": "0",
                    "errmsg": "下单成功"
                })


# 上传个人头像
class UploadsPersonalView(View):
    def post(self, request):
        avatar = request.FILES.get('avatar')
        key = storage(avatar.read())
        # 拼接路由
        avatar_url = URL + '/' + key

        request.user.avatar = avatar_url
        request.user.save()
        return JsonResponse({
                    "data": {
                        "avatar_url": avatar_url
                    },
                    "errno": "0",
                    "errmsg": "头像上传成功"
                })


class UserInfoView(View):
    def get(self, request):
        avatar = str(request.user.avatar)
        date_joined = request.user.date_joined
        print(type(date_joined))
        ctime = date_joined.strftime("%Y-%m-%d %H:%M:%S")

        return JsonResponse({
                    "data": {
                        "avatar_url": avatar,
                        "create_time": ctime,
                        "mobile": request.user.mobile,
                        "name": request.user.username,
                        "user_id": request.user.id
                    },
                    "errmsg": "OK",
                    "errno": "0"
                })


class UploadsHouselView(View):
    def post(self, request, house_id):
        house = House.objects.get(id=house_id)
        house_image = request.FILES.get('house_image')
        key = storage(house_image.read())
        # 拼接路由
        image_url = URL + '/' + key

        house.index_image_url = image_url
        house.save()
        return JsonResponse({
                    "data": {
                        "url": image_url
                    },
                    "errno": "0",
                    "errmsg": "图片上传成功"
                })


class SSSView(View):
    def get(self, request):
        user = User.objects.get(id=4)
        print(user.avatar, type(user.avatar))
        return JsonResponse({"errno": "0", "errmsg": "图片上传成功", "avatar": str(user.avatar)})